/**
 * 场景管理路由
 */
const express = require('express');
const router = express.Router({ mergeParams: true }); // 允许访问父路由的params
const fs = require('fs').promises;
const fsSync = require('fs');
const path = require('path');
const multer = require('multer');
const { PROJECTS_DIR } = require('../utils/constants');
const { generateId } = require('../utils/helpers');
const { splitTreeData, rebuildFullTree } = require('../utils/treeUtils');
const {
    readProjectsIndex,
    saveProjectsIndex,
    readProjectConfig,
    saveProjectConfig
} = require('../services/projectService');

/**
 * 清空指定项目的缓存文件夹
 * @param {string} projectPath - 项目路径（如 'project-1761612215028-2n6km35'）
 */
async function clearProjectCache(projectPath) {
    try {
        const projectCacheDir = path.join(PROJECTS_DIR, 'cache', 'uploadmodel', projectPath);
        
        // 检查项目缓存目录是否存在
        if (!fsSync.existsSync(projectCacheDir)) {
            console.log(`ℹ️ [Clear Cache] 项目缓存目录不存在，无需清空: ${projectPath}`);
            return;
        }
        
        // 删除项目缓存目录
        await fs.rm(projectCacheDir, { recursive: true, force: true });
        console.log(`🗑️ [Clear Cache] 项目缓存已删除: ${projectPath}`);
        
        // 重新创建空的项目缓存目录
        await fs.mkdir(projectCacheDir, { recursive: true });
        console.log(`✅ [Clear Cache] 项目缓存目录已重建: ${projectPath}`);
        
    } catch (error) {
        console.error(`❌ [Clear Cache] 清空项目缓存失败 (${projectPath}):`, error);
        // 不抛出错误，避免影响主流程
    }
}

// 配置multer用于环境模型上传
const storage = multer.diskStorage({
    destination: async (req, file, cb) => {
        const { id, sceneId } = req.params;
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return cb(new Error('项目不存在'));
        }
        
        const uploadDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId, 'environment');
        
        // 确保目录存在
        if (!fsSync.existsSync(uploadDir)) {
            await fs.mkdir(uploadDir, { recursive: true });
        }
        
        cb(null, uploadDir);
    },
    filename: (req, file, cb) => {
        // 处理中文文件名乱码：将 latin1 编码的文件名转换为 UTF-8
        const originalName = Buffer.from(file.originalname, 'latin1').toString('utf-8');
        cb(null, originalName);
    }
});

const envModelUpload = multer({
    storage: storage,
    limits: {
        fileSize: 100 * 1024 * 1024 // 限制100MB
    },
    fileFilter: (req, file, cb) => {
        const allowedExts = ['.glb', '.gltf', '.fbx'];
        const ext = path.extname(file.originalname).toLowerCase();
        
        if (allowedExts.includes(ext)) {
            cb(null, true);
        } else {
            cb(new Error('不支持的文件格式，仅支持: .glb, .gltf, .fbx'));
        }
    }
});

/**
 * 向项目添加场景
 * POST /api/projects/:id/scenes
 * Body: { name, description? }
 */
router.post('/', async (req, res) => {
    try {
        const { id } = req.params;
        const { name, description = '' } = req.body;
        
        if (!name) {
            return res.status(400).json({
                success: false,
                error: '场景名称不能为空'
            });
        }
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 读取项目配置
        const config = await readProjectConfig(projectMeta.path);
        
        // 生成场景ID
        const sceneId = generateId('scene');
        
        // 创建场景元数据（只保存在project.json中）
        const sceneMetadata = {
            id: sceneId,
            name: name,
            type: 'GroundScene', // 默认地面场景
            description: description,
            icon: '🏞️',
            sceneFile: `scenes/${sceneId}/config.json`, // 场景数据文件路径
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString()
        };
        
        // 创建完整的场景数据（保存在独立文件中）
        const sceneData = {
            id: sceneId,
            name: name,
            type: 'GroundScene',
            description: description,
            objects: [], // 场景中的物体
            lights: [
                {
                    type: 'AmbientLight',
                    color: 0xffffff,
                    intensity: 0.5
                },
                {
                    type: 'DirectionalLight',
                    color: 0xffffff,
                    intensity: 0.8,
                    position: [10, 10, 5],
                    castShadow: true
                }
            ],
            camera: {
                position: [8, 6, 8],
                target: [0, 0, 0]
            },
            settings: {
                showAxes: false, // 不显示坐标轴
                showGrid: true,
                backgroundColor: 0x87ceeb
            },
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString()
        };
        
        // 创建场景文件夹
        const projectDir = path.join(PROJECTS_DIR, projectMeta.path);
        const scenesDir = path.join(projectDir, 'scenes');
        const sceneDir = path.join(scenesDir, sceneId);
        await fs.mkdir(sceneDir, { recursive: true });
        
        // 保存场景配置到独立文件
        const sceneFilePath = path.join(sceneDir, 'config.json');
        await fs.writeFile(sceneFilePath, JSON.stringify(sceneData, null, 2), 'utf-8');
        
        // 创建空的场景树配置文件
        const treeFilePath = path.join(sceneDir, 'tree.json');
        const emptyTreeData = {
            root: {
                id: 'root',
                name: 'Scene Root',
                type: 'root',
                visible: true,
                locked: false,
                userData: {},
                children: []
            },
            nodeCount: 1,
            exportedAt: new Date().toISOString()
        };
        await fs.writeFile(treeFilePath, JSON.stringify(emptyTreeData, null, 2), 'utf-8');
        console.log('✅ 场景树配置文件已创建:', treeFilePath);
        
        // 添加场景元数据到项目配置
        config.scenes.push(sceneMetadata);
        
        // 如果是第一个场景，设为默认场景
        if (config.scenes.length === 1) {
            config.defaultScene = sceneId;
        }
        
        config.updatedAt = new Date().toISOString();
        projectMeta.updatedAt = new Date().toISOString();
        
        // 保存项目配置
        await saveProjectConfig(projectMeta.path, config);
        await saveProjectsIndex(index);
        
        console.log('✅ 场景添加成功:', name);
        console.log('   - 场景文件:', sceneFilePath);
        res.json({
            success: true,
            data: sceneMetadata
        });
        
    } catch (error) {
        console.error('❌ 添加场景失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 更新场景信息
 * PUT /api/projects/:id/scenes/:sceneId
 * Body: { name?, description? }
 */
router.put('/:sceneId', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        const { name, description } = req.body;
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 读取项目配置
        const config = await readProjectConfig(projectMeta.path);
        
        const scene = config.scenes.find(s => s.id === sceneId);
        if (!scene) {
            return res.status(404).json({
                success: false,
                error: '场景不存在'
            });
        }
        
        // 更新字段
        if (name !== undefined) {
            scene.name = name;
        }
        if (description !== undefined) {
            scene.description = description;
        }
        
        scene.updatedAt = new Date().toISOString();
        config.updatedAt = new Date().toISOString();
        projectMeta.updatedAt = new Date().toISOString();
        
        // 保存配置
        await saveProjectConfig(projectMeta.path, config);
        await saveProjectsIndex(index);
        
        console.log('✅ 场景更新成功:', scene.name);
        res.json({
            success: true,
            data: scene
        });
        
    } catch (error) {
        console.error('❌ 更新场景失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 更新场景settings（如天空盒配置）
 * PUT /api/projects/:id/scenes/:sceneId/settings
 * Body: { skybox?, backgroundColor?, showAxes?, showGrid? }
 */
router.put('/:sceneId/settings', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        const settingsUpdate = req.body;
        
        console.log(`🔧 [Settings API] 更新场景settings: project=${id}, scene=${sceneId}`);
        console.log('   更新内容:', settingsUpdate);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 读取场景配置文件
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const sceneFilePath = path.join(sceneDir, 'config.json');
        
        if (!fsSync.existsSync(sceneFilePath)) {
            return res.status(404).json({
                success: false,
                error: '场景配置文件不存在'
            });
        }
        
        const sceneConfig = JSON.parse(await fs.readFile(sceneFilePath, 'utf-8'));
        
        // 更新settings
        if (!sceneConfig.settings) {
            sceneConfig.settings = {};
        }
        
        // 合并更新的settings
        Object.assign(sceneConfig.settings, settingsUpdate);
        
        sceneConfig.updatedAt = new Date().toISOString();
        
        // 保存场景配置
        await fs.writeFile(sceneFilePath, JSON.stringify(sceneConfig, null, 2), 'utf-8');
        
        console.log('✅ [Settings API] 场景settings更新成功');
        res.json({
            success: true,
            data: sceneConfig.settings
        });
        
    } catch (error) {
        console.error('❌ [Settings API] 更新场景settings失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 删除场景
 * DELETE /api/projects/:id/scenes/:sceneId
 */
router.delete('/:sceneId', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 读取项目配置
        const config = await readProjectConfig(projectMeta.path);
        
        const sceneIndex = config.scenes.findIndex(s => s.id === sceneId);
        if (sceneIndex === -1) {
            return res.status(404).json({
                success: false,
                error: '场景不存在'
            });
        }
        
        const sceneToDelete = config.scenes[sceneIndex];
        
        // 不允许删除默认场景
        if (config.defaultScene === sceneId) {
            return res.status(400).json({
                success: false,
                error: '不能删除默认场景，请先设置其他场景为默认'
            });
        }
        
        // 删除场景
        const deletedScene = config.scenes.splice(sceneIndex, 1)[0];
        
        // 删除场景文件夹
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', deletedScene.id);
        try {
            await fs.rm(sceneDir, { recursive: true, force: true });
            console.log('✅ 场景文件夹已删除:', sceneDir);
        } catch (err) {
            console.warn('⚠️ 删除场景文件夹失败:', err.message);
        }
        
        config.updatedAt = new Date().toISOString();
        projectMeta.updatedAt = new Date().toISOString();
        
        // 保存配置
        await saveProjectConfig(projectMeta.path, config);
        await saveProjectsIndex(index);
        
        console.log('✅ 场景删除成功:', deletedScene.name);
        res.json({
            success: true,
            message: '场景删除成功'
        });
        
    } catch (error) {
        console.error('❌ 删除场景失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 更新场景顺序
 * PUT /api/projects/:id/scenes/order
 * Body: { sceneIds: ['scene1', 'scene2', 'scene3'] }
 */
router.put('/order', async (req, res) => {
    try {
        const { id } = req.params;
        const { sceneIds } = req.body;
        
        if (!Array.isArray(sceneIds)) {
            return res.status(400).json({
                success: false,
                error: '场景ID列表格式错误'
            });
        }
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 读取项目配置
        const config = await readProjectConfig(projectMeta.path);
        
        // 根据新顺序重新排列场景
        const orderedScenes = [];
        sceneIds.forEach(sceneId => {
            const scene = config.scenes.find(s => s.id === sceneId);
            if (scene) {
                orderedScenes.push(scene);
            }
        });
        
        // 添加任何未在列表中的场景（防止数据丢失）
        config.scenes.forEach(scene => {
            if (!sceneIds.includes(scene.id)) {
                orderedScenes.push(scene);
            }
        });
        
        config.scenes = orderedScenes;
        config.updatedAt = new Date().toISOString();
        projectMeta.updatedAt = new Date().toISOString();
        
        // 保存配置
        await saveProjectConfig(projectMeta.path, config);
        await saveProjectsIndex(index);
        
        console.log('✅ 场景顺序已更新');
        res.json({
            success: true,
            message: '场景顺序更新成功'
        });
    } catch (error) {
        console.error('❌ 更新场景顺序失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 设置默认场景
 * POST /api/projects/:id/scenes/:sceneId/set-default
 */
router.post('/:sceneId/set-default', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 读取项目配置
        const config = await readProjectConfig(projectMeta.path);
        
        const scene = config.scenes.find(s => s.id === sceneId);
        if (!scene) {
            return res.status(404).json({
                success: false,
                error: '场景不存在'
            });
        }
        
        config.defaultScene = sceneId;
        config.updatedAt = new Date().toISOString();
        projectMeta.updatedAt = new Date().toISOString();
        
        // 保存配置
        await saveProjectConfig(projectMeta.path, config);
        await saveProjectsIndex(index);
        
        console.log('✅ 默认场景已设置:', scene.name);
        res.json({
            success: true,
            message: '默认场景设置成功'
        });
        
    } catch (error) {
        console.error('❌ 设置默认场景失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 获取场景配置（包括settings等）
 * GET /api/projects/:id/scenes/:sceneId/config
 */
router.get('/:sceneId/config', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        
        console.log(`📋 [Config API] 获取场景配置: project=${id}, scene=${sceneId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 读取场景配置文件
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const sceneFilePath = path.join(sceneDir, 'config.json');
        
        if (!fsSync.existsSync(sceneFilePath)) {
            return res.status(404).json({
                success: false,
                error: '场景配置文件不存在'
            });
        }
        
        const sceneConfig = JSON.parse(await fs.readFile(sceneFilePath, 'utf-8'));
        console.log(`✅ [Config API] 场景配置读取成功`);
        
        res.json({
            success: true,
            data: sceneConfig
        });
        
    } catch (error) {
        console.error('❌ [Config API] 获取场景配置失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 获取场景的nodes数据（用于材质引用等信息查询）
 * GET /api/projects/:id/scenes/:sceneId/nodes
 */
router.get('/:sceneId/nodes', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        
        console.log(`\n📦 [Nodes API] 获取场景nodes数据: project=${id}, scene=${sceneId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 场景nodes数据文件路径
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const nodesFilePath = path.join(sceneDir, 'nodes.json');
        
        // 检查文件是否存在
        if (!fsSync.existsSync(nodesFilePath)) {
            console.log(`ℹ️ [Nodes API] nodes.json不存在，返回空数据`);
            return res.json({
                success: true,
                data: {
                    nodes: [],
                    nodeCount: 0
                }
            });
        }
        
        // 读取nodes数据
        const nodesData = JSON.parse(await fs.readFile(nodesFilePath, 'utf-8'));
        console.log(`✅ [Nodes API] nodes数据读取成功，节点数: ${nodesData.nodeCount || 0}`);
        
        res.json({
            success: true,
            data: nodesData
        });
        
    } catch (error) {
        console.error('❌ [Nodes API] 获取nodes数据失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 获取场景的树结构数据
 * GET /api/projects/:id/scenes/:sceneId/tree
 * 返回完整的树结构给编辑端（编辑端期待 tree.root 格式）
 */
router.get('/:sceneId/tree', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        
        console.log(`\n🌲 [Tree API] 获取场景树数据: project=${id}, scene=${sceneId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            console.log(`❌ [Tree API] 项目不存在: ${id}`);
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        console.log(`✅ [Tree API] 项目找到: ${projectMeta.name} (${projectMeta.path})`);
        
        // 场景树数据文件路径
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const treeFilePath = path.join(sceneDir, 'tree.json');
        const nodesFilePath = path.join(sceneDir, 'nodes.json');
        
        console.log(`📂 [Tree API] 树文件路径: ${treeFilePath}`);
        
        // 检查文件是否存在
        if (!fsSync.existsSync(treeFilePath)) {
            // 如果不存在，创建空树文件（新格式）
            console.log(`ℹ️ [Tree API] 树文件不存在，自动创建空树配置`);
            
            const emptyTreeData = {
                root: {
                    id: 'root',
                    name: 'Scene Root',
                    type: 'root',
                    visible: true,
                    locked: false,
                    userData: {},
                    children: []
                },
                nodeCount: 1,
                exportedAt: new Date().toISOString()
            };
            
            // 拆分并保存
            await fs.mkdir(sceneDir, { recursive: true });
            const splitData = splitTreeData(emptyTreeData);
            await fs.writeFile(treeFilePath, JSON.stringify(splitData.tree, null, 2), 'utf-8');
            await fs.writeFile(nodesFilePath, JSON.stringify(splitData.nodes, null, 2), 'utf-8');
            console.log(`✅ [Tree API] 场景树配置文件已自动创建（新格式）`);
            
            // 🗑️ 场景加载完成，清空当前项目缓存
            await clearProjectCache(projectMeta.path);
            
            return res.json(emptyTreeData);
        }
        
        // 读取树数据
        console.log(`📖 [Tree API] 读取树文件...`);
        const treeData = JSON.parse(await fs.readFile(treeFilePath, 'utf-8'));
        
        // 检查是否是新格式（relations数组）
        if (treeData.relations && Array.isArray(treeData.relations)) {
            console.log(`📊 [Tree API] 检测到新格式（relations数组），读取nodes.json...`);
            
            // 读取节点配置
            if (!fsSync.existsSync(nodesFilePath)) {
                console.error(`❌ [Tree API] nodes.json不存在，但tree.json是新格式`);
                return res.status(500).json({
                    success: false,
                    error: '数据不完整：缺少nodes.json'
                });
            }
            
            const nodesData = JSON.parse(await fs.readFile(nodesFilePath, 'utf-8'));
            console.log(`✅ [Tree API] 节点配置读取成功，节点数: ${nodesData.nodeCount || 0}`);
            
            // 重建完整树结构（编辑端期待的格式）
            console.log(`🔄 [Tree API] 重建完整树结构...`);
            const fullTree = rebuildFullTree(treeData.relations, nodesData.nodes);
            
            const responseData = {
                root: fullTree,
                nodeCount: treeData.nodeCount,
                exportedAt: treeData.splitAt
            };
            
            console.log(`✅ [Tree API] 返回完整树结构`);
            
            // 🗑️ 场景加载完成，清空当前项目缓存
            await clearProjectCache(projectMeta.path);
            
            return res.json(responseData);
        }
        
        // 旧格式，直接返回
        console.log(`📊 [Tree API] 旧格式数据，直接返回`);
        console.log(`✅ [Tree API] 树数据读取成功，节点数: ${treeData.nodeCount || 0}`);
        
        // 🗑️ 场景加载完成，清空当前项目缓存
        await clearProjectCache(projectMeta.path);
        
        res.json(treeData);
        
    } catch (error) {
        console.error('❌ [Tree API] 获取场景树数据失败:');
        console.error('   错误类型:', error.name);
        console.error('   错误消息:', error.message);
        console.error('   错误堆栈:', error.stack);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 保存场景的树结构数据
 * POST /api/projects/:id/scenes/:sceneId/tree
 */
router.post('/:sceneId/tree', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        const treeData = req.body;
        
        console.log(`\n💾 [Tree API] 保存场景树数据: project=${id}, scene=${sceneId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 场景目录
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const treeFilePath = path.join(sceneDir, 'tree.json');
        const nodesFilePath = path.join(sceneDir, 'nodes.json');
        
        // 确保场景目录存在
        await fs.mkdir(sceneDir, { recursive: true });
        
        // 拆分树数据为 tree.json (关系) 和 nodes.json (配置)
        console.log(`📊 [Tree API] 拆分树数据...`);
        const splitData = splitTreeData(treeData);
        
        console.log(`   - 节点数: ${splitData.tree.nodeCount}`);
        console.log(`   - 关系数: ${splitData.tree.relations.length}`);
        
        // 保存树关系
        await fs.writeFile(treeFilePath, JSON.stringify(splitData.tree, null, 2), 'utf-8');
        console.log(`✅ [Tree API] 树关系已保存: tree.json`);
        
        // 保存节点配置
        await fs.writeFile(nodesFilePath, JSON.stringify(splitData.nodes, null, 2), 'utf-8');
        console.log(`✅ [Tree API] 节点配置已保存: nodes.json`);
        
        res.json({
            success: true,
            message: '场景树保存成功'
        });
        
    } catch (error) {
        console.error('❌ [Tree API] 保存场景树数据失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 获取节点的子树信息（包括所有子孙节点）
 * GET /api/projects/:id/scenes/:sceneId/nodes/:nodeId/subtree
 */
router.get('/:sceneId/nodes/:nodeId/subtree', async (req, res) => {
    try {
        const { id, sceneId, nodeId } = req.params;
        
        console.log(`\n🌳 [Subtree API] 获取节点子树: project=${id}, scene=${sceneId}, node=${nodeId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const treeFilePath = path.join(sceneDir, 'tree.json');
        const nodesFilePath = path.join(sceneDir, 'nodes.json');
        
        if (!fsSync.existsSync(treeFilePath) || !fsSync.existsSync(nodesFilePath)) {
            return res.status(404).json({
                success: false,
                error: '场景树数据不存在'
            });
        }
        
        const treeData = JSON.parse(await fs.readFile(treeFilePath, 'utf-8'));
        const nodesData = JSON.parse(await fs.readFile(nodesFilePath, 'utf-8'));
        
        // 创建节点映射
        const nodesMap = new Map();
        nodesData.nodes.forEach(node => {
            nodesMap.set(node.id, node);
        });
        
        // 创建关系映射
        const relationsMap = new Map();
        treeData.relations.forEach(rel => {
            relationsMap.set(rel.id, rel);
        });
        
        // 检查节点是否存在
        if (!nodesMap.has(nodeId)) {
            return res.status(404).json({
                success: false,
                error: '节点不存在'
            });
        }
        
        // 递归收集所有子孙节点
        const allNodes = [];
        function collectSubtree(currentNodeId, depth = 0) {
            const node = nodesMap.get(currentNodeId);
            const relation = relationsMap.get(currentNodeId);
            
            if (!node || !relation) return;
            
            allNodes.push({
                nodeId: node.id,
                nodeName: node.name,
                nodeType: node.type,
                modelId: node.components?.model?.modelId || null,
                isRoot: depth === 0,
                depth: depth
            });
            
            // 递归处理子节点
            if (relation.children && relation.children.length > 0) {
                relation.children.forEach(childId => {
                    collectSubtree(childId, depth + 1);
                });
            }
        }
        
        collectSubtree(nodeId);
        
        console.log(`✅ [Subtree API] 收集到 ${allNodes.length} 个节点`);
        
        res.json({
            success: true,
            data: {
                nodes: allNodes,
                totalCount: allNodes.length
            }
        });
        
    } catch (error) {
        console.error('❌ [Subtree API] 获取节点子树失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 删除节点（级联删除所有子节点，并更新模型和材质引用）
 * DELETE /api/projects/:id/scenes/:sceneId/nodes/:nodeId
 */
router.delete('/:sceneId/nodes/:nodeId', async (req, res) => {
    try {
        const { id, sceneId, nodeId } = req.params;
        
        console.log(`\n🗑 [Delete Node API] 删除节点: project=${id}, scene=${sceneId}, node=${nodeId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const treeFilePath = path.join(sceneDir, 'tree.json');
        const nodesFilePath = path.join(sceneDir, 'nodes.json');
        
        if (!fsSync.existsSync(treeFilePath) || !fsSync.existsSync(nodesFilePath)) {
            return res.status(404).json({
                success: false,
                error: '场景树数据不存在'
            });
        }
        
        const treeData = JSON.parse(await fs.readFile(treeFilePath, 'utf-8'));
        const nodesData = JSON.parse(await fs.readFile(nodesFilePath, 'utf-8'));
        
        // 创建节点映射
        const nodesMap = new Map();
        nodesData.nodes.forEach(node => {
            nodesMap.set(node.id, node);
        });
        
        // 创建关系映射
        const relationsMap = new Map();
        treeData.relations.forEach(rel => {
            relationsMap.set(rel.id, rel);
        });
        
        // 检查节点是否存在
        if (!nodesMap.has(nodeId)) {
            return res.status(404).json({
                success: false,
                error: '节点不存在'
            });
        }
        
        // 收集所有要删除的节点ID及其引用的资源（包括子孙节点）
        const nodesToDelete = new Set();
        const modelsToUpdate = new Map(); // modelId -> Set of nodeIds
        const materialsToUpdate = new Map(); // materialId -> Set of nodeIds
        
        function collectNodesToDelete(currentNodeId) {
            nodesToDelete.add(currentNodeId);
            
            const node = nodesMap.get(currentNodeId);
            if (node) {
                // ⚠️ components 是数组，需要遍历查找 model 组件
                if (Array.isArray(node.components)) {
                    const modelComponent = node.components.find(c => c.type === 'model');
                    
                    // 收集模型引用
                    if (modelComponent && modelComponent.modelId) {
                        const modelId = modelComponent.modelId;
                        if (!modelsToUpdate.has(modelId)) {
                            modelsToUpdate.set(modelId, new Set());
                        }
                        modelsToUpdate.get(modelId).add(currentNodeId);
                    }
                    
                    // 收集材质引用（从 meshMaterials 中）
                    if (modelComponent && modelComponent.meshMaterials) {
                        Object.values(modelComponent.meshMaterials).forEach(binding => {
                            if (binding.materialId && binding.materialId !== "0") {
                                const materialId = binding.materialId;
                                if (!materialsToUpdate.has(materialId)) {
                                    materialsToUpdate.set(materialId, new Set());
                                }
                                materialsToUpdate.get(materialId).add(currentNodeId);
                            }
                        });
                    }
                }
            }
            
            const relation = relationsMap.get(currentNodeId);
            if (relation && relation.children) {
                relation.children.forEach(childId => {
                    collectNodesToDelete(childId);
                });
            }
        }
        
        collectNodesToDelete(nodeId);
        
        console.log(`📋 [Delete Node API] 将删除 ${nodesToDelete.size} 个节点`);
        console.log(`📋 [Delete Node API] 需要更新 ${modelsToUpdate.size} 个模型的引用`);
        console.log(`📋 [Delete Node API] 需要更新 ${materialsToUpdate.size} 个材质的引用`);
        
        // ===== 1. 更新模型引用 =====
        if (modelsToUpdate.size > 0) {
            const modelsDir = path.join(PROJECTS_DIR, projectMeta.path, 'models');
            
            let modelsUpdated = 0;
            for (const [modelId, nodeIds] of modelsToUpdate) {
                const modelConfigPath = path.join(modelsDir, `${modelId}.json`);
                
                if (fsSync.existsSync(modelConfigPath)) {
                    try {
                        const modelData = await fs.readFile(modelConfigPath, 'utf-8');
                        const model = JSON.parse(modelData);
                        
                        if (model.usedByNodes) {
                            const beforeCount = model.usedByNodes.length;
                            
                            // 移除所有被删除节点的引用
                            model.usedByNodes = model.usedByNodes.filter(ref => 
                                !(ref.sceneId === sceneId && nodeIds.has(ref.nodeId))
                            );
                            
                            const afterCount = model.usedByNodes.length;
                            const removed = beforeCount - afterCount;
                            
                            if (removed > 0) {
                                model.updatedAt = new Date().toISOString();
                                await fs.writeFile(modelConfigPath, JSON.stringify(model, null, 2), 'utf-8');
                                modelsUpdated++;
                                console.log(`   ✅ 模型 ${modelId}: 移除了 ${removed} 个节点引用`);
                            }
                        }
                    } catch (error) {
                        console.warn(`⚠️ 更新模型 ${modelId} 引用失败:`, error.message);
                    }
                }
            }
            
            if (modelsUpdated > 0) {
                console.log(`✅ [Delete Node API] 已更新 ${modelsUpdated} 个模型的引用`);
            }
        }
        
        // ===== 2. 更新材质引用 =====
        if (materialsToUpdate.size > 0) {
            const materialsConfigPath = path.join(PROJECTS_DIR, projectMeta.path, 'materials', 'materials.json');
            
            if (fsSync.existsSync(materialsConfigPath)) {
                const materialsData = await fs.readFile(materialsConfigPath, 'utf-8');
                const materialsConfig = JSON.parse(materialsData);
                
                let materialsUpdated = 0;
                for (const [materialId, nodeIds] of materialsToUpdate) {
                    const material = materialsConfig.materials.find(m => m.id === materialId);
                    if (material) {
                        // 初始化 usedByNodes 如果不存在
                        if (!material.usedByNodes) {
                            material.usedByNodes = [];
                        }
                        
                        const beforeCount = material.usedByNodes.length;
                        
                        // 移除所有被删除节点的引用
                        material.usedByNodes = material.usedByNodes.filter(ref => 
                            !(ref.sceneId === sceneId && nodeIds.has(ref.nodeId))
                        );
                        
                        const afterCount = material.usedByNodes.length;
                        const removed = beforeCount - afterCount;
                        
                        if (removed > 0) {
                            material.updatedAt = new Date().toISOString();
                            materialsUpdated++;
                            console.log(`   ✅ 材质 ${materialId}: 移除了 ${removed} 个节点引用`);
                        }
                    }
                }
                
                if (materialsUpdated > 0) {
                    await fs.writeFile(materialsConfigPath, JSON.stringify(materialsConfig, null, 2), 'utf-8');
                    console.log(`✅ [Delete Node API] 已更新 ${materialsUpdated} 个材质的引用`);
                }
            }
        }
        
        // ===== 3. 从父节点的children数组中移除 =====
        const parentRelation = treeData.relations.find(rel => 
            rel.children && rel.children.includes(nodeId)
        );
        
        if (parentRelation) {
            parentRelation.children = parentRelation.children.filter(id => id !== nodeId);
            console.log(`✅ [Delete Node API] 已从父节点 ${parentRelation.id} 中移除引用`);
        }
        
        // ===== 4. 删除所有节点及其关系 =====
        treeData.relations = treeData.relations.filter(rel => !nodesToDelete.has(rel.id));
        nodesData.nodes = nodesData.nodes.filter(node => !nodesToDelete.has(node.id));
        
        // 更新节点数量
        treeData.nodeCount = treeData.relations.length;
        nodesData.nodeCount = nodesData.nodes.length;
        
        // 保存更新后的数据
        await fs.writeFile(treeFilePath, JSON.stringify(treeData, null, 2), 'utf-8');
        await fs.writeFile(nodesFilePath, JSON.stringify(nodesData, null, 2), 'utf-8');
        
        console.log(`✅ [Delete Node API] 节点删除成功，共删除 ${nodesToDelete.size} 个节点`);
        
        res.json({
            success: true,
            data: {
                totalDeleted: nodesToDelete.size,
                deletedNodes: Array.from(nodesToDelete),
                modelsUpdated: modelsToUpdate.size,
                materialsUpdated: materialsToUpdate.size
            }
        });
        
    } catch (error) {
        console.error('❌ [Delete Node API] 删除节点失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 获取场景的环境配置
 * GET /api/projects/:id/scenes/:sceneId/environment
 */
router.get('/:sceneId/environment', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        
        console.log(`\n🌍 [Environment API] 获取环境配置: project=${id}, scene=${sceneId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 环境配置文件路径
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const environmentFilePath = path.join(sceneDir, 'environment.json');
        
        // 检查文件是否存在
        if (!fsSync.existsSync(environmentFilePath)) {
            console.log(`ℹ️ [Environment API] environment.json不存在，返回默认配置`);
            // 返回默认环境配置
            const defaultConfig = {
                environmentModel: null,
                skybox: {
                    enabled: false,
                    type: 'color',
                    color: '#1a1a1a',
                    textureUrl: null
                },
                ambientLight: {
                    enabled: true,
                    intensity: 0.5,
                    color: '#ffffff'
                }
            };
            return res.json(defaultConfig);
        }
        
        // 读取环境配置
        const environmentData = JSON.parse(await fs.readFile(environmentFilePath, 'utf-8'));
        console.log(`✅ [Environment API] 环境配置读取成功`);
        
        res.json(environmentData);
        
    } catch (error) {
        console.error('❌ [Environment API] 获取环境配置失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 保存场景的环境配置
 * POST /api/projects/:id/scenes/:sceneId/environment
 */
router.post('/:sceneId/environment', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        const environmentConfig = req.body;
        
        console.log(`\n💾 [Environment API] 保存环境配置: project=${id}, scene=${sceneId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 场景目录
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const environmentFilePath = path.join(sceneDir, 'environment.json');
        
        // 确保场景目录存在
        await fs.mkdir(sceneDir, { recursive: true });
        
        // 添加时间戳
        const configWithTimestamp = {
            ...environmentConfig,
            updatedAt: new Date().toISOString()
        };
        
        // 保存环境配置
        await fs.writeFile(environmentFilePath, JSON.stringify(configWithTimestamp, null, 2), 'utf-8');
        console.log(`✅ [Environment API] 环境配置已保存: environment.json`);
        
        res.json({
            success: true,
            message: '环境配置保存成功'
        });
        
    } catch (error) {
        console.error('❌ [Environment API] 保存环境配置失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 上传环境模型（自动删除旧模型）
 * POST /api/projects/:id/scenes/:sceneId/environment/model
 */
router.post('/:sceneId/environment/model', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        
        console.log(`\n📤 [Environment Model API] 上传环境模型: project=${id}, scene=${sceneId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const envDir = path.join(sceneDir, 'environment');
        const environmentFilePath = path.join(sceneDir, 'environment.json');
        
        // 🗑️ 删除旧的环境模型文件
        if (fsSync.existsSync(envDir)) {
            const files = await fs.readdir(envDir);
            for (const file of files) {
                const filePath = path.join(envDir, file);
                await fs.unlink(filePath);
                console.log(`🗑️ [Environment Model API] 删除旧模型: ${file}`);
            }
        }
        
        // 📤 上传新的环境模型
        await new Promise((resolve, reject) => {
            envModelUpload.single('file')(req, res, (err) => {
                if (err) {
                    reject(err);
                } else {
                    resolve();
                }
            });
        });
        
        if (!req.file) {
            return res.status(400).json({
                success: false,
                error: '未上传文件'
            });
        }
        
        console.log(`✅ [Environment Model API] 环境模型上传成功: ${req.file.filename}`);
        
        // 📝 自动更新环境配置
        let envConfig = {
            environmentModel: null,
            skybox: {
                enabled: false,
                type: 'color',
                color: '#1a1a1a',
                textureUrl: null
            },
            ambientLight: {
                enabled: true,
                intensity: 0.5,
                color: '#ffffff'
            }
        };
        
        let isFirstUpload = true;
        let existingTransform = null;
        
        // 读取现有配置（如果存在）
        if (fsSync.existsSync(environmentFilePath)) {
            envConfig = JSON.parse(await fs.readFile(environmentFilePath, 'utf-8'));
            
            // 如果已有环境模型配置，保存其变换信息
            if (envConfig.environmentModel && envConfig.environmentModel.filename) {
                isFirstUpload = false;
                existingTransform = {
                    position: envConfig.environmentModel.position || { x: 0, y: 0, z: 0 },
                    rotation: envConfig.environmentModel.rotation || { x: 0, y: 0, z: 0 },
                    scale: envConfig.environmentModel.scale || { x: 1, y: 1, z: 1 }
                };
                console.log(`📍 [Environment Model API] 保留现有位置配置:`, existingTransform.position);
            }
        }
        
        // 更新环境模型配置
        if (isFirstUpload) {
            // 🆕 首次上传：设置在原点
            console.log(`🆕 [Environment Model API] 首次上传，设置在原点`);
            envConfig.environmentModel = {
                filename: req.file.filename,
                position: { x: 0, y: 0, z: 0 },
                rotation: { x: 0, y: 0, z: 0 },
                scale: { x: 1, y: 1, z: 1 }
            };
        } else {
            // 🔄 后续上传：保持用户调整的位置
            console.log(`🔄 [Environment Model API] 后续上传，保留用户调整的位置`);
            envConfig.environmentModel = {
                filename: req.file.filename,
                position: existingTransform.position,
                rotation: existingTransform.rotation,
                scale: existingTransform.scale
            };
        }
        
        envConfig.updatedAt = new Date().toISOString();
        
        // 保存配置
        await fs.mkdir(sceneDir, { recursive: true });
        await fs.writeFile(environmentFilePath, JSON.stringify(envConfig, null, 2), 'utf-8');
        console.log(`📝 [Environment Model API] 环境配置已更新`);
        
        res.json({
            success: true,
            filename: req.file.filename,
            size: req.file.size,
            isFirstUpload: isFirstUpload,
            transform: envConfig.environmentModel,
            message: '环境模型上传成功'
        });
        
    } catch (error) {
        console.error('❌ [Environment Model API] 上传环境模型失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 获取环境模型文件
 * GET /api/projects/:id/scenes/:sceneId/environment/model/:filename
 */
router.get('/:sceneId/environment/model/:filename', async (req, res) => {
    try {
        const { id, sceneId, filename } = req.params;
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        const modelPath = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId, 'environment', filename);
        
        if (!fsSync.existsSync(modelPath)) {
            return res.status(404).json({
                success: false,
                error: '环境模型文件不存在'
            });
        }
        
        // 发送文件
        res.sendFile(modelPath);
        
    } catch (error) {
        console.error('❌ [Environment Model API] 获取环境模型失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

/**
 * 删除环境模型
 * DELETE /api/projects/:id/scenes/:sceneId/environment/model
 */
router.delete('/:sceneId/environment/model', async (req, res) => {
    try {
        const { id, sceneId } = req.params;
        
        console.log(`\n🗑 [Environment Model API] 删除环境模型: project=${id}, scene=${sceneId}`);
        
        const index = await readProjectsIndex();
        const projectMeta = index.projects.find(p => p.id === id);
        
        if (!projectMeta) {
            return res.status(404).json({
                success: false,
                error: '项目不存在'
            });
        }
        
        // 读取环境配置获取当前模型文件名
        const sceneDir = path.join(PROJECTS_DIR, projectMeta.path, 'scenes', sceneId);
        const environmentFilePath = path.join(sceneDir, 'environment.json');
        
        if (fsSync.existsSync(environmentFilePath)) {
            const envConfig = JSON.parse(await fs.readFile(environmentFilePath, 'utf-8'));
            
            if (envConfig.environmentModel && envConfig.environmentModel.filename) {
                const modelPath = path.join(sceneDir, 'environment', envConfig.environmentModel.filename);
                
                // 删除模型文件
                if (fsSync.existsSync(modelPath)) {
                    await fs.unlink(modelPath);
                    console.log(`✅ [Environment Model API] 模型文件已删除: ${envConfig.environmentModel.filename}`);
                }
                
                // 更新环境配置
                envConfig.environmentModel = null;
                envConfig.updatedAt = new Date().toISOString();
                await fs.writeFile(environmentFilePath, JSON.stringify(envConfig, null, 2), 'utf-8');
            }
        }
        
        res.json({
            success: true,
            message: '环境模型删除成功'
        });
        
    } catch (error) {
        console.error('❌ [Environment Model API] 删除环境模型失败:', error);
        res.status(500).json({
            success: false,
            error: error.message
        });
    }
});

module.exports = router;

